package models

import (
	"gitee.com/tangrx/go-admin/utils/config"
	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
	"log"
	"strconv"
)

type DB struct {
	*sqlx.DB
}

func GetConnectstring() string {
	return config.GetStr("db")
}
func OpenDB(conn ...string) (*DB, error) {
	connString := ""
	defaultConnString := GetConnectstring()
	if len(conn) > 0 {
		connString = conn[0]
	}
	if len(connString) == 0 {
		connString = defaultConnString
	}

	db, err := sqlx.Open("postgres", connString)
	if err != nil {
		return nil, err
	}
	return &DB{DB: db}, err
}

func Page(conn string, strSelect string, strFrom string, strWhere string, strOrder string, page PageStruct, args ...interface{}) *PageResult {
	return PageHavePre(conn, "", strSelect, strFrom, strWhere, strOrder, page, args...)
}

func PageHavePre(conn string, strPreSql string, strSelect string, strFrom string, strWhere string, strOrder string, page PageStruct, args ...interface{}) *PageResult {
	result := &PageResult{Status: "200", Msg: ""}
	if page.Current < 1 {
		page.Current = 1
	}
	if page.Size <= 0 {
		page.Size = 100
	}
	if len(strSelect) == 0 {
		strSelect = "*"
	}
	sqlWhere := " "
	if len(strWhere) > 0 {
		sqlWhere += " where " + strWhere
	}

	db, err := OpenDB(conn)
	defer db.Close()
	if err != nil {
		log.Fatalln(err)
		result.Status = "100"
		result.Msg = err.Error()
		return result
	}
	sqlOrderby := ""
	if len(strOrder) > 0 {
		sqlOrderby = " order by " + strOrder
	}
	sqlTotal := strPreSql + " select count(*) from " + strFrom + sqlWhere
	var count int
	log.Println(sqlTotal)
	err = db.Get(&count, sqlTotal, args...)
	if err != nil {
		log.Fatalln(err)
		result.Status = "100"
		result.Msg = err.Error()
		return result
	}
	page.Total = count
	if count > 0 && count < (page.Current-1)*page.Size {
		page.Current = count / page.Size
		end := count % page.Size
		if end > 0 {
			page.Current = page.Current + 1
		}
	}
	result.Page = page

	sqlList := strPreSql + " select " + strSelect + " from " + strFrom + sqlWhere + sqlOrderby + " limit " + strconv.Itoa(page.Size) + " "
	if page.Current > 1 {
		sqlList += " offset " + strconv.Itoa((page.Current-1)*page.Size)
	}
	log.Println(sqlList)
	rows, err1 := db.Queryx(sqlList, args...)
	if err1 != nil {
		log.Fatalln(err1)
		result.Status = "100"
		result.Msg = err1.Error()
		return result
	}
	dataList := make([]interface{}, 0)
	for rows.Next() {
		data := make(map[string]interface{})
		rows.MapScan(data)
		dataList = append(dataList, data)
	}
	result.SetList(&dataList)
	return result
}
